"""
矿山安全评估模型管理器（单例模式）

该模块实现了模型handler的单例模式管理，确保模型只加载一次，
避免重复初始化和内存浪费。

作者：矿山安全评价系统开发团队
版本：1.0.0
更新时间：2025-10-19
"""

import os
import sys
import logging
from typing import Optional
from threading import Lock

logger = logging.getLogger(__name__)


class ModelHandlerSingleton:
    """
    模型Handler单例管理器
    
    使用线程安全的单例模式，确保模型只加载一次，
    并在整个应用生命周期中复用。
    """
    
    _instance = None
    _lock = Lock()
    _handler = None
    _initialized = False
    
    def __new__(cls):
        """
        实现线程安全的单例模式
        """
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super(ModelHandlerSingleton, cls).__new__(cls)
        return cls._instance
    
    def __init__(self):
        """
        初始化单例（只执行一次）
        """
        if not self._initialized:
            self._initialize_handler()
            self._initialized = True
    
    def _initialize_handler(self):
        """
        初始化模型handler
        """
        try:
            # 添加模型目录到Python路径
            model_dir_path = os.path.join(
                os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 
                'AHP-MIV-BP_0.93'
            )
            
            if model_dir_path not in sys.path:
                sys.path.insert(0, model_dir_path)
            
            # 动态导入模型handler
            from model_handler import MineEvaluationHandler
            
            # 初始化模型handler
            self._handler = MineEvaluationHandler(
                model_dir=os.path.join(model_dir_path, 'saved_models'),
                timestamp='20251019_150609'
            )
            
            logger.info("✓ 模型Handler单例初始化成功")
            
        except Exception as e:
            logger.error(f"✗ 模型Handler单例初始化失败: {e}", exc_info=True)
            self._handler = None
    
    def get_handler(self) -> Optional['MineEvaluationHandler']:
        """
        获取模型handler实例
        
        Returns:
            MineEvaluationHandler: 模型handler实例，如果初始化失败则返回None
        """
        if not self._initialized:
            self._initialize_handler()
            self._initialized = True
        
        return self._handler
    
    def is_available(self) -> bool:
        """
        检查模型handler是否可用
        
        Returns:
            bool: True如果模型可用，False否则
        """
        return self._handler is not None
    
    def predict_safety_level(self, features: list) -> str:
        """
        预测安全等级
        
        Args:
            features: 15个特征值的列表（0-1范围）
            
        Returns:
            str: 预测的安全等级（A级/B级/C级/D级）
        """
        if not self.is_available():
            logger.warning("模型Handler不可用，使用默认安全等级")
            return 'C级(一般)'
        
        try:
            # 使用模型预测
            predicted_level = self._handler.predict_one(features)
            
            # 映射模型输出到系统等级
            level_mapping = {
                'I类': 'A级(优秀)',
                'II类': 'B级(良好)', 
                'III类': 'C级(一般)',
                'IV类': 'D级(较差)'
            }
            
            safety_level = level_mapping.get(predicted_level, 'C级(一般)')
            logger.info(f"模型预测结果: {predicted_level} -> {safety_level}")
            
            return safety_level
            
        except Exception as e:
            logger.error(f"模型预测失败: {e}", exc_info=True)
            return 'C级(一般)'
    
    def get_model_info(self) -> dict:
        """
        获取模型信息
        
        Returns:
            dict: 模型信息字典
        """
        if not self.is_available():
            return {
                'status': 'unavailable',
                'message': '模型Handler未初始化或初始化失败'
            }
        
        try:
            return {
                'status': 'available',
                'feature_names': self._handler.get_feature_names(),
                'classes': self._handler.get_classes().tolist(),
                'selected_features': self._handler.get_selected_features()
            }
        except Exception as e:
            logger.error(f"获取模型信息失败: {e}")
            return {
                'status': 'error',
                'message': str(e)
            }


# 全局单例实例
model_handler_singleton = ModelHandlerSingleton()


def get_model_handler() -> Optional['MineEvaluationHandler']:
    """
    获取模型handler实例的便捷函数
    
    Returns:  
        MineEvaluationHandler: 模型handler实例
    """
    return model_handler_singleton.get_handler()


def predict_safety_level(features: list) -> str:
    """
    预测安全等级的便捷函数
    
    Args:
        features: 15个特征值的列表（0-1范围）
        
    Returns:
        str: 预测的安全等级
    """
    return model_handler_singleton.predict_safety_level(features)


def is_model_available() -> bool:
    """
    检查模型是否可用的便捷函数
    
    Returns:
        bool: True如果模型可用
    """
    return model_handler_singleton.is_available()


def get_model_info() -> dict:
    """
    获取模型信息的便捷函数
    
    Returns:
        dict: 模型信息
    """
    return model_handler_singleton.get_model_info()
